此篇,採用比較嚴謹的方式,去建置AWS的服務,也是以同樣的架構,做對比,如下圖:
今日會介紹需要自己設置route table,連接internet gateway,甚至是規劃subnet CIDR
首先,還是要先建立一個VPC,但要把AZ跟NAT設定成0,不然會自動使用預設值建立。
myvpc = ec2.Vpc(self, "cdk-vpc",
max_azs=0,
nat_gateways=0,
cidr="10.0.0.0/16",
enable_dns_hostnames=True,
enable_dns_support=True
)
再來需要建立自己的subnet,這裡的public-subnet是可以隨便定義,不會影響後面程式的調用
mysubnet = ec2.Subnet(self, "public-subnet",
availability_zone="us-east-2b",
cidr_block="10.0.30.0/24",
vpc_id=myvpc.vpc_id,
map_public_ip_on_launch=True)
cidr_block:研讀前面章節去設定適合的CIDR。如果要事後再新增subnet,mask就設定大一點,留些空間,才可以切新的subnet出來
將建立好的subnet設定route table,以及internet gateway,這樣User才可以訪問到EC2
mysubnet.add_default_internet_route(myvpc.internet_gateway_id, gateway_attachment=myvpc)
接下來的SG inbound rules和OS設定都一樣沒有去更動。如果企業在設定SG inbound rules,可以在description說明,這條inbound rules的用途,在日後要修改或新增才不會誤刪掉導致其他服務訪問失敗
mysg = ec2.SecurityGroup(self, "cdk-sg-it",
vpc=myvpc,
allow_all_outbound=True,
description="it demo 30 days",
security_group_name="cdk-sg")
mysg.add_ingress_rule(peer=ec2.Peer.any_ipv4(), connection=ec2.Port.tcp(22), description="cdk remote access")
mysg.add_ingress_rule(peer=ec2.Peer.any_ipv4(), connection=ec2.Port.tcp(80), description="cdk use browser to access")
ami = ec2.AmazonLinuxImage(cpu_type=ec2.AmazonLinuxCpuType.X86_64,
edition=ec2.AmazonLinuxEdition.STANDARD,
generation=ec2.AmazonLinuxGeneration.AMAZON_LINUX_2,
storage=ec2.AmazonLinuxStorage.GENERAL_PURPOSE,
virtualization=ec2.AmazonLinuxVirt.HVM,
)
最後就是建立EC2
myec2 = ec2.Instance(self, "myEC2",
instance_name="cdk-ec2-test",
instance_type=ec2.InstanceType("t3.micro"),
machine_image=ami,
allow_all_outbound=True,
availability_zone="us-east-2b",
key_name="itdemo",
security_group=mysg,
vpc_subnets=ec2.SubnetSelection(subnets=[mysubnet]),
user_data=ec2.UserData.custom(userdata),
vpc=myvpc,
block_devices=[ec2.BlockDevice(device_name="/dev/xvda",
volume=ec2.BlockDeviceVolume.ebs(volume_size=10,
volume_type=ec2.EbsDeviceVolumeType.GP3),
mapping_enabled=True)])
vpc_subnets:SubnetSelection選擇的參數是subnets,這個subnets需要是List的型態,所以需要做轉態的動作,以及直接填入上面設定好的mysubnet這個變數,就可以把EC2建立在us-east-2b以及private ip為10.0.30.X(X:2-254)。
從這兩篇文章可以看出明顯的對比,subnet cidr、route table,以及attach internet gateway。一個是可以快速建立,另一個則是比較嚴謹的做法,嚴謹的做法好處是在使用console上可以熟悉操作以及設定
from aws_cdk import core as cdk
from aws_cdk import (
aws_ec2 as ec2,
core
)
with open("./ittest2/userdata.sh", "r", encoding='utf-8') as file:
userdata = file.read()
class Ittest2Stack(cdk.Stack):
def __init__(self, scope: cdk.Construct, construct_id: str, **kwargs) -> None:
super().__init__(scope, construct_id, **kwargs)
# The code that defines your stack goes here
myvpc = ec2.Vpc(self, "cdk-vpc",
max_azs=0,
nat_gateways=0,
cidr="10.0.0.0/16",
enable_dns_hostnames=True,
enable_dns_support=True
)
mysubnet = ec2.Subnet(self, "public-subnet",
availability_zone="us-east-2b",
cidr_block="10.0.30.0/24",
vpc_id=myvpc.vpc_id,
map_public_ip_on_launch=True)
mysubnet.add_default_internet_route(myvpc.internet_gateway_id, gateway_attachment=myvpc)
mysg = ec2.SecurityGroup(self, "cdk-sg-it",
vpc=myvpc,
allow_all_outbound=True,
description="it demo 30 days",
security_group_name="cdk-sg")
mysg.add_ingress_rule(peer=ec2.Peer.any_ipv4(), connection=ec2.Port.tcp(22), description="cdk remote access")
mysg.add_ingress_rule(peer=ec2.Peer.any_ipv4(), connection=ec2.Port.tcp(80), description="cdk use browser to access")
ami = ec2.AmazonLinuxImage(cpu_type=ec2.AmazonLinuxCpuType.X86_64,
edition=ec2.AmazonLinuxEdition.STANDARD,
generation=ec2.AmazonLinuxGeneration.AMAZON_LINUX_2,
storage=ec2.AmazonLinuxStorage.GENERAL_PURPOSE,
virtualization=ec2.AmazonLinuxVirt.HVM,
)
myec2 = ec2.Instance(self, "myEC2",
instance_name="cdk-ec2-test",
instance_type=ec2.InstanceType("t3.micro"),
machine_image=ami,
allow_all_outbound=True,
availability_zone="us-east-2b",
key_name="itdemo",
security_group=mysg,
vpc_subnets=ec2.SubnetSelection(subnets=[mysubnet]),
user_data=ec2.UserData.custom(userdata),
vpc=myvpc,
block_devices=[ec2.BlockDevice(device_name="/dev/xvda",
volume=ec2.BlockDeviceVolume.ebs(volume_size=10, volume_type=ec2.EbsDeviceVolumeType.GP3),
mapping_enabled=True)])
core.CfnOutput(self, "publicIP", value=myec2.instance_public_ip)
core.CfnOutput(self, "publicDNS", value=myec2.instance_public_dns_name)
core.CfnOutput(self, "privateIP", value=myec2.instance_private_ip)
core.CfnOutput(self, "privateDNS", value=myec2.instance_private_dns_name)